import java.math.BigDecimal;
import java.time.Duration;
import java.time.LocalDateTime;

public class Bill {
    private final int minMinute = 20;
    private final double minUnivalent = 0.05;
    private final double maxUnivalent = 0.10;
    private final double minFee = 1.00;

    boolean isLessOrEqualMinMinute(final long timeLength) {
        return timeLength <= minMinute;
    }

    int isEndTimeSubOrStartTimeSubOrDoNothing(final boolean inDayLightSavingOfStartTime,
                                              final boolean inDayLightSavingOfEndTime) {
        if (inDayLightSavingOfEndTime && !inDayLightSavingOfStartTime) {
            return 1;
        } else if (inDayLightSavingOfStartTime && !inDayLightSavingOfEndTime) {
            return 2;
        }
        return 0;
    }

    long calculateTimeSpan(final LocalDateTime startTime,
                           final boolean inDayLightSavingOfStartTime,
                           final LocalDateTime endTime,
                           final boolean inDayLightSavingOfEndTime) {
        LocalDateTime startNewTime = startTime;
        LocalDateTime endNewTime = endTime;
        final int transTime = 60;
        int result = isEndTimeSubOrStartTimeSubOrDoNothing(inDayLightSavingOfStartTime, inDayLightSavingOfEndTime);
        if (result == 1) {
            endNewTime = endTime.minusHours(1);
        } else if (result == 2) {
            startNewTime = startTime.minusHours(1);
        }
        Duration duration = Duration.between(startNewTime, endNewTime);
        long timeSpan = duration.getSeconds();
        timeSpan = timeSpan / transTime + (timeSpan % transTime == 0 ? 0 : 1);
        return timeSpan;
    }

    BigDecimal calculateFee(final long timeLength) {
        if (isLessOrEqualMinMinute(timeLength)) {
            BigDecimal bigDecimal = new BigDecimal(timeLength * minUnivalent);
            return bigDecimal;
        } else {
            BigDecimal bigDecimal = new BigDecimal(minFee);
            bigDecimal = bigDecimal.add(new BigDecimal((timeLength - minMinute) * maxUnivalent));
            return bigDecimal;
        }

    }

    Double calculate(final int year, final int month, final int day,
                     final int startHour, final int startMinute, final int startSecond,
                     final int endHour, final int endMinute, final int endSecond,
                     final int inDayLightSavingOfStartTime, final int inDayLightSavingOfEndTime) {
        LocalDateTime startTime = LocalDateTime.of(year, month, day, startHour, startMinute, startSecond);
        LocalDateTime endTime = LocalDateTime.of(year, month, day, endHour, endMinute, endSecond);
        LocalDateTime now = LocalDateTime.now();
        boolean inDayLightSavingOfStart = inDayLightSavingOfStartTime == 1;
        boolean inDayLightSavingOfEnd = inDayLightSavingOfEndTime == 1;
        long timeSpan = calculateTimeSpan(startTime, inDayLightSavingOfStart, endTime, inDayLightSavingOfEnd);
        BigDecimal money = calculateFee(timeSpan);
        return money.doubleValue();
    }
}
